package com.winter.filter;

import com.alibaba.fastjson.JSON;
import com.winter.base.WinterResponse;
import com.winter.utils.IpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.StopWatch;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

/**
 * @author JinHao
 * Date: 2023/12/21 11:22
 */
@Slf4j
@WebFilter(urlPatterns = "/*")
public class WebCmsFilter implements Filter {

    private static final String PASSWORD = "password";
    private static final String WINTER_COM = "43.138.49.138";
    private static final String OPTIONS_METHOD = "OPTIONS";
    private static final String OBLIQUE_STR = "/";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("过滤器初始化");
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        String ip = IpUtil.getRealIp(request);
        String uri = request.getRequestURI();
        StringBuffer url = request.getRequestURL();

        PrintWriter writer;
        Map<String, String[]> parameterMap = request.getParameterMap();
        if (parameterMap.containsKey(PASSWORD)) {
            parameterMap.put(PASSWORD, new String[]{"******"});
        }
        String parameterStr = JSON.toJSONString(parameterMap);

        // 跨域处理
        String origin = request.getHeader("Origin");
        if (StringUtils.isNotBlank(origin)) {
            if (origin.contains(WINTER_COM)) {
                response.setContentType("application/json; charset=utf-8");
                response.setHeader("Access-Control-Allow-Credentials", "true");
                response.setHeader("Access-Control-Allow-Headers", "Origin, Accept, Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
                response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
                response.setHeader("Access-Control-Max-Age", "3600");
                response.setHeader("Access-Control-Allow-Origin", origin);
            }
        }

        // 浏览器对复杂跨域请求的预请求，试探服务器响应是否通过，跳过
        if (OPTIONS_METHOD.equals(request.getMethod())) {
            filterChain.doFilter(request, response);
            return;
        }

        // 健康检测
        if (OBLIQUE_STR.equals(uri)) {
            response.setContentType("application/json; charset=utf-8");
            writer = response.getWriter();
            writer.write(JSON.toJSONString(WinterResponse.success()));
            writer.flush();
            writer.close();
            return;
        }

        // 记录请求信息
        log.info("请求INFO: ip:{}, url:{}, uri:{}, param:{}", ip, url, uri, parameterStr);
        filterChain.doFilter(request, response);
        // 访问结束
        stopWatch.stop();
        log.info("请求结束: ip:{}, url:{}, uri:{}, 耗时:{}ms", ip, url, uri, stopWatch.getTotalTimeMillis());
    }

    @Override
    public void destroy() {
        log.info("过滤器已销毁");
        Filter.super.destroy();
    }
}
